One of my favorite attributes of Python as a language is that when you encounter something you've not seen before, it generally "just works" the way you expect it to. The else clause of a for or while loop is the exception to that rule.

Consider the familiar if statement:


In [13]:
x = True
if x:
    print("x is truthy")
else:
    print("x is falsy")


x is truthy

When the if's condition is met (it is "truthy"), the code belonging to the if block is executed. When the if's condition is not met, the else block executes instead. In no case will both blocks execute. This is pretty basic Python - hell, it's pretty basic programming. It works the same in every language I've ever learned.

Given this, let's take a look at the following:


In [20]:
numbers = tuple()

for value in numbers:
    print("Inside the loop: value={}".format(value))
else:
    print("... else ...")


... else ...

Given a tuple containing no items, only the else block executes. So far, so good - this is working just like if..else. But what happens when we try the same thing, but with a 3-tuple?


In [23]:
numbers = (0, 1, 2)

for value in numbers:
    print("Inside the loop: value={}".format(value))
else:
    print("... else ...")


Inside the loop: value=0
Inside the loop: value=1
Inside the loop: value=2
... else ...

Whoa!

Unlike the if..else statement, it seems like the else block in a for..else always executes. If that's the case, then why have the statement at all? Wouldn't just putting the code inline after the loop do the same thing? Sort of - but what's actually happening is that the else block gets executed when the iterable is exhausted on a for loop, and when the condition is "falsy" on a while loop.

That means constructs like this are possible:


In [35]:
numbers = (0, 1, 2)

for value in numbers:
    print("Inside the loop: value={}".format(value))
    if value == 1:
        break
else:
    print("... else ...")


Inside the loop: value=0
Inside the loop: value=1

Because we used break to exit the loop before numbers never ran out of values, the else block is not triggered. The else block gives you an easy to execute code when a loop completes, but skip that same code if the loop exits early.

See Also